<script setup lang="ts">
import dayjs from 'dayjs';
import { fileNameForUploadFile, uploadImageFile } from '/@/utils/file';
import { My as AppNutIconMy, Plus as AppNutIconPlus } from '@nutui/icons-vue-taro';
import {
  showLoading,
  hideLoading,
  showToast,
  reLaunch,
  setStorage,
  chooseImage,
  getCurrentInstance,
} from '@tarojs/taro';
import { onMounted, reactive, ref } from 'vue';
import { cloneDeep } from 'lodash';
import {
  QUERY_DETAIL_BY_BATCH_NO,
  INSERT,
} from '/@/api/modules/visitor/visitor-appointment-record';
import IMG_ICON_COMMON_PAGE_WAIT from '/@/assets/image/icon/common-page-wait.png';
import { getSysImgUrl } from '/@/utils/index';
import { VisitorRegisterV2 } from './index.d';
import { formRules } from './state';
import compressImage from '../../face-upload/utils/image-compress';

const visitorRegisterV2FormRef = ref();

/**
 * @description 当前路由信息
 */
const params = getCurrentInstance().router?.params as unknown as {
  code: string;
};

const state = reactive<VisitorRegisterV2>({
  authMsg: '访客邀请码验证中...',
  auditStatus: 0,
  sexPickerIsShow: false,
  calendarIsShow: false,
  startTimePickerIsShow: false,
  endTimePickerIsShow: false,
  activePersonIdx: 0,
});

const formState = reactive<VisitorAppointmentRecordApi.InsertReq>({
  visitorAppointmentDto: {
    id: '',
    startTime: undefined,
    endTime: undefined,
    purpose: '',
  },
  content: [
    {
      personName: '',
      sex: undefined,
      phone: '',
      idNo: '',
      carNo: '',
      visitorWorkUint: '',
      photoUrl: '',
    },
  ],
});

/**
 * @function 上传头像
 * @param idx 当前处理的同行人索引
 */
function uploadAvatar(idx: number) {
  chooseImage({
    count: 1,
    sizeType: ['compressed'],
    success: (res) => {
      const { originalFileObj, path } = res.tempFiles[0];
      const suffix = originalFileObj?.name.substring(originalFileObj?.name.lastIndexOf('.')) || ''; //取文件名后缀
      const fileName = fileNameForUploadFile(suffix);
      const originalFileName = originalFileObj?.name || '';
      showLoading({ title: '上传中...' });
      if (originalFileObj && originalFileObj?.size > 200 * 1024) {
        //先压缩
        compressImage([res.tempFiles[0].originalFileObj]).then((list: string[]) => {
          uploadImageFile(list[0], originalFileName, fileName, 'face', (url: string) => {
            formState.content[idx].fileType = 1;
            formState.content[idx].fileName = fileName;
            formState.content[idx].fileUrl = url;
            hideLoading();
          });
        });
      } else {
        uploadImageFile(path, originalFileName, fileName, 'visitor', (url: string) => {
          formState.content[idx].fileType = 1;
          formState.content[idx].fileName = fileName;
          formState.content[idx].fileUrl = url;
          hideLoading();
          showToast({
            title: '头像照片上传成功',
            icon: 'success',
          });
        });
      }
    },
  });
}

/**
 * @function 确认提交
 */
function submit() {
  visitorRegisterV2FormRef.value.validate().then(({ valid }) => {
    if (!valid) return;
    showLoading({ title: '加载中...' });

    const _form = cloneDeep(formState);

    INSERT(_form).then(() => {
      hideLoading();
      setStorage({
        key: 'visitorInfo',
        data: _form,
        success: () => {
          reLaunch({
            url: `/pages/visitor/register-v2/index?code=${params.code}`,
          });
        },
      });
    });
  });
}

onMounted(() => {
  if (!params.code) {
    state.authMsg = '访客邀请码未知！';
  } else {
    QUERY_DETAIL_BY_BATCH_NO({
      visitorAppointmentBatchNo: params.code,
    })
      .then((res) => {
        if (res.visitorAppointmentDto.auditStatus === 1) {
          reLaunch({
            url: `/pages/visitor/permit-v2/index?code=${params.code}`,
          });
        } else if (res.content && res.content.length) {
          state.auditStatus = res.visitorAppointmentDto.auditStatus || 0;
          state.authMsg = `您的访客申请${
            { 1: '已通过', 2: '已拒绝', 3: '正在等待审批, 请稍后', 4: '已撤销', 5: '已取消' }[
              res.visitorAppointmentDto.auditStatus || 3
            ]
          }`;
        } else {
          setTimeout(() => {
            state.auditStatus = 0;
            formState.visitorAppointmentDto.id = res.visitorAppointmentDto.id;
            formState.visitorAppointmentDto.batchNo = res.visitorAppointmentDto.batchNo;
          }, 1000);
        }
      })
      .catch((err) => {
        state.authMsg = err.comResp.err || err.comResp.tip;
      });
  }
});
</script>

<template>
  <view class="visitor-register-v2 app-page--1">
    <view class="visitor-register-v2__header app-page__header">
      <text>金华市公安局江南分局访客登记</text>
    </view>
    <view v-if="state.auditStatus" class="visitor-register-v2__auth-msg-wrapper">
      <image
        v-if="state.auditStatus === 3"
        class="visitor-register-v2__audit-status-3-img"
        :src="IMG_ICON_COMMON_PAGE_WAIT"
      />
      <view>
        <text>{{ state.authMsg }}</text>
      </view>
    </view>
    <scroll-view v-else class="app-page__wrapper" :scroll-y="true" :lower-threshold="100">
      <nut-form
        :model-value="formState"
        :rules="formRules"
        class="visitor-register-v2__form"
        ref="visitorRegisterV2FormRef"
      >
        <nut-form-item
          required
          label="来访时间"
          prop="visitorAppointmentDto.startTime"
          :rules="formRules.startTime"
          label-width="100px"
          label-align="left"
          error-message-align="left"
        >
          <nut-input
            :model-value="
              formState.visitorAppointmentDto.startTime
                ? dayjs(formState.visitorAppointmentDto.startTime).format('YYYY-MM-DD')
                : ''
            "
            placeholder="请选择来访时间"
            :border="false"
            readonly
            @click="
              () => {
                state.calendarIsShow = !state.calendarIsShow;
              }
            "
          />
        </nut-form-item>
        <nut-form-item
          v-if="false"
          required
          label="预计来访时间"
          prop="visitorAppointmentDto.startTime"
          :rules="formRules.startTime"
          label-width="100px"
          label-align="left"
          error-message-align="left"
        >
          <nut-input
            :model-value="
              formState.visitorAppointmentDto.startTime
                ? dayjs(formState.visitorAppointmentDto.startTime).format('YYYY-MM-DD HH:mm')
                : ''
            "
            placeholder="请选择预计来访时间"
            :border="false"
            readonly
            @click="
              () => {
                state.startTimePickerIsShow = !state.startTimePickerIsShow;
              }
            "
          />
        </nut-form-item>
        <nut-form-item
          v-if="false"
          required
          label="预计离开时间"
          prop="visitorAppointmentDto.endTime"
          :rules="formRules.endTime"
          label-width="100px"
          label-align="left"
          error-message-align="left"
        >
          <nut-input
            :model-value="
              formState.visitorAppointmentDto.endTime
                ? dayjs(formState.visitorAppointmentDto.endTime).format('YYYY-MM-DD HH:mm')
                : ''
            "
            placeholder="请选择预计离开时间"
            :border="false"
            readonly
            @click="
              () => {
                if (!formState.visitorAppointmentDto.startTime) {
                  showToast({
                    title: '请选择预计来访时间',
                    icon: 'error',
                  });
                  return;
                }
                state.endTimePickerIsShow = !state.endTimePickerIsShow;
              }
            "
          />
        </nut-form-item>
        <nut-form-item
          required
          label="来访事由"
          prop="visitorAppointmentDto.purpose"
          :rules="formRules.purpose"
          label-width="100px"
          label-align="left"
          error-message-align="left"
        >
          <nut-input
            v-model="formState.visitorAppointmentDto.purpose"
            placeholder="请输入来访事由"
            :border="false"
            clearable
          />
        </nut-form-item>

        <view
          v-for="(item, index) in formState.content"
          :key="item.id || index"
          class="visitor-register-v2__person-item"
        >
          <nut-form-item
            required
            label="姓名"
            :prop="`content.${index}.personName`"
            :rules="formRules.personName"
            label-width="100px"
            label-align="left"
            error-message-align="left"
          >
            <nut-input
              v-model="item.personName"
              placeholder="请输入姓名"
              :border="false"
              clearable
              max-length="10"
              show-word-limit
            />
          </nut-form-item>
          <nut-form-item
            v-if="false"
            required
            label="性别"
            :prop="`content.${index}.sex`"
            :rules="formRules.sex"
            label-width="100px"
            label-align="left"
            error-message-align="left"
          >
            <nut-input
              :model-value="item.sex ? { 1: '男', 2: '女' }[item.sex as 1 | 2] : ''"
              placeholder="请选择性别"
              :border="false"
              readonly
              @click="
                () => {
                  state.sexPickerIsShow = !state.sexPickerIsShow;
                  state.activePersonIdx = index;
                }
              "
            />
          </nut-form-item>
          <nut-form-item
            required
            label="联系电话"
            :prop="`content.${index}.phone`"
            :rules="formRules.phone"
            label-width="100px"
            label-align="left"
            error-message-align="left"
          >
            <nut-input
              v-model="item.phone"
              placeholder="请输入联系电话"
              type="number"
              :border="false"
              clearable
              max-length="11"
              show-word-limit
            />
          </nut-form-item>
          <nut-form-item
            required
            label="身份证"
            :prop="`content.${index}.idNo`"
            :rules="formRules.idNo"
            label-width="100px"
            label-align="left"
            error-message-align="left"
          >
            <nut-input
              v-model="item.idNo"
              placeholder="请输入身份证"
              :border="false"
              clearable
              max-length="18"
              show-word-limit
            />
          </nut-form-item>
          <nut-form-item
            required
            label="头像照片"
            :prop="`content.${index}.fileUrl`"
            :rules="formRules.fileUrl"
            label-width="100px"
            label-align="left"
            error-message-align="left"
          >
            <nut-avatar
              class="visitor-register-v2__avatar"
              size="large"
              shape="square"
              @click="uploadAvatar(index)"
            >
              <image v-if="item.fileUrl" :src="getSysImgUrl(item.fileUrl)" />
              <app-nut-icon-my v-else />
            </nut-avatar>
          </nut-form-item>
          <nut-form-item
            label="车牌号"
            label-width="100px"
            label-align="left"
            error-message-align="left"
          >
            <nut-input
              v-model="item.carNo"
              placeholder="请输入车牌号（选填）"
              :border="false"
              clearable
              max-length="8"
              show-word-limit
            />
          </nut-form-item>
          <nut-form-item
            label="单位"
            label-width="100px"
            label-align="left"
            error-message-align="left"
          >
            <nut-input
              v-model="item.visitorWorkUint"
              placeholder="请输入单位（选填）"
              :border="false"
              clearable
              max-length="30"
              show-word-limit
            />
          </nut-form-item>
          <nut-form-item v-if="formState.content && formState.content.length > 1" label=" ">
            <nut-button
              type="danger"
              size="mini"
              @click="
                () => {
                  formState.content.splice(index, 1);
                }
              "
            >
              删除
            </nut-button>
          </nut-form-item>
        </view>
      </nut-form>
      <view class="visitor-register-v2__add-person-btn-wrapper">
        <nut-button
          class="visitor-register-v2__add-person-btn"
          block
          @click="
            () => {
              formState.content.push({
                personName: '',
                sex: undefined,
                phone: '',
                idNo: '',
                carNo: '',
                visitorWorkUint: '',
                photoUrl: '',
              });
            }
          "
        >
          <template #icon>
            <app-nut-icon-plus />
          </template>
          添加同行人员
        </nut-button>
      </view>
    </scroll-view>
    <view v-if="!state.auditStatus" class="visitor-register-v2__footer">
      <nut-button type="info" block @click="submit()">提交</nut-button>
    </view>

    <nut-calendar
      v-model:visible="state.calendarIsShow"
      :default-value="dayjs(formState.visitorAppointmentDto.startTime).format('YYYY-MM-DD')"
      :start-date="dayjs().format('YYYY-MM-DD')"
      :end-date="dayjs().format('YYYY-12-31')"
      @choose="(date: string | string[]) => {
        formState.visitorAppointmentDto.startTime = dayjs(`${date[3]} 08:00`).valueOf();
        formState.visitorAppointmentDto.endTime = dayjs(`${date[3]} 20:00`).valueOf();
      }"
    />

    <nut-popup v-model:visible="state.sexPickerIsShow" position="bottom">
      <nut-picker
        v-model:value="formState.content[state.activePersonIdx].sex"
        title="请选择性别"
        :columns="[
          { text: '男', value: 1 },
          { text: '女', value: 2 },
        ]"
        @confirm="
          ({ selectedOptions }) => {
            formState.content[state.activePersonIdx].sex = selectedOptions[0].value;
            state.sexPickerIsShow = false;
          }
        "
        @cancel="state.sexPickerIsShow = false"
      />
    </nut-popup>

    <nut-popup v-model:visible="state.startTimePickerIsShow" position="bottom">
      <nut-date-picker
        :model-value="
          formState.visitorAppointmentDto.startTime
            ? new Date(dayjs(formState.visitorAppointmentDto.startTime).format('YYYY-MM-DD HH:mm'))
            : ''
        "
        type="datetime"
        is-show-chinese
        :minute-step="30"
        :min-date="new Date()"
        :max-date="new Date(dayjs().format('YYYY/12/31'))"
        @cancel="
          () => {
            state.startTimePickerIsShow = false;
          }
        "
        @confirm="
          ({ selectedValue }) => {
            formState.visitorAppointmentDto.startTime = dayjs(
              `${selectedValue[0]}-${selectedValue[1]}-${selectedValue[2]} ${selectedValue[3]}:${selectedValue[4]}:00`,
            ).valueOf();

            state.startTimePickerIsShow = false;
            formState.visitorAppointmentDto.endTime = undefined;
          }
        "
      />
    </nut-popup>

    <nut-popup v-model:visible="state.endTimePickerIsShow" position="bottom">
      <nut-date-picker
        :model-value="
          formState.visitorAppointmentDto.endTime
            ? new Date(dayjs(formState.visitorAppointmentDto.endTime).format('YYYY-MM-DD HH:mm'))
            : ''
        "
        type="datetime"
        is-show-chinese
        :minute-step="30"
        :min-date="
          formState.visitorAppointmentDto.startTime
            ? new Date(dayjs(formState.visitorAppointmentDto.startTime).format('YYYY/MM/DD HH:mm'))
            : new Date()
        "
        :max-date="
          formState.visitorAppointmentDto.startTime
            ? new Date(dayjs(formState.visitorAppointmentDto.startTime).format('YYYY/MM/DD 23:59'))
            : new Date()
        "
        @cancel="
          () => {
            state.endTimePickerIsShow = false;
          }
        "
        @confirm="
          ({ selectedValue }) => {
            formState.visitorAppointmentDto.endTime = dayjs(
              `${selectedValue[0]}-${selectedValue[1]}-${selectedValue[2]} ${selectedValue[3]}:${selectedValue[4]}:00`,
            ).valueOf();

            state.endTimePickerIsShow = false;
          }
        "
      />
    </nut-popup>
  </view>
</template>

<style lang="scss">
@import './index.scss';
</style>
